#include "can.h"
#include "separator.h"

#define TIMER_CYCLE    (10)                       // 定时器中断（ms）
#define MAX_TIME_COUNT (5 * (1000 / TIMER_CYCLE)) // 判定CAN保温未收到的时间

// 初始化CAN报文结构
static void can_data_init(can_data_t *can_data)
{
    can_data->temperature_msg   = message_no_received;
    can_data->motor_control_msg = message_no_received;
    can_data->engine_speed_msg  = message_no_received;

    can_data->driect_control_cmd = 0;
    can_data->target_speed       = 0;
    can_data->engine_speed       = 0;
    can_data->temperature        = 0.0f;
}

/**
 * @brief	结构初始化
 * @param	None
 * @retval	None
 * @note	初始化油分器结构体
 */
void separator_init(separator_t *separator)
{
    separator->engine_state    = engine_stop;
    separator->target_pressure = -1.0f;
    separator->work_current    = 0.0f;

    pressure_sensor_init(&separator->press_sensor);
    can_data_init(&separator->can_data);
}

/**
 * @param	根据发动机转速报文和传感器压力更新发动机运行状态
 * @note	电机转动会产生负压，无法准确判定发动机工作情况，暂时不可使用
 */
void update_engine_state(separator_t *separator)
{
    if (separator->can_data.engine_speed_msg == message_is_received)
    {
        if (separator->can_data.engine_speed > 10)
        {
            separator->engine_state = engine_start;
        }
        else
        {
            separator->engine_state = engine_stop;
        }
    }
    else
    {
        if (separator->press_sensor.pressure_value > 0.3)
        {
            separator->engine_state = engine_start;
        }
        else
        {
            separator->engine_state = engine_stop;
        }
    }
}

/**
 * @brief	通过CAN获取发动机状态
 * @note	仅仅通过CAN总线上的发动机报文判断发动机工作状态
 */
void update_engine_state_only_by_can(separator_t *separator)
{
    if (separator->can_data.engine_speed > 10)
    {
        separator->engine_state = engine_start;
    }
    else
    {
        separator->engine_state = engine_stop;
    }
}

// 判定报文未接受计数值，定时器中断中累加，收到时清零
static unsigned short engine_speed_msg_no_received_count  = 0;
static unsigned short motor_control_msg_no_received_count = 0;

/**
 * @brief	将控制指令未接收计数值清零
 * @note	对外的接口函数
 */
void clear_motor_ctrl_count(void)
{
    motor_control_msg_no_received_count = 0;
}

/**
 * @brief	累加控制指令未接收计数值
 * @note	对外的接口函数
 */
void accumulate_motor_ctrl_count(void)
{
    if (motor_control_msg_no_received_count >= MAX_TIME_COUNT)
    {
        motor_control_msg_no_received_count = MAX_TIME_COUNT;
    }
    motor_control_msg_no_received_count++;
}

/**
 * @brief	将转速报文未接收计数值清零
 * @note	对外的接口函数
 */
void clear_engine_speed_count(void)
{
    engine_speed_msg_no_received_count = 0;
}

/**
 * @brief	累加转速报文未接收计数值
 * @note	对外的接口函数
 */
void accumulate_engine_speed_count(void)
{
    if (engine_speed_msg_no_received_count >= MAX_TIME_COUNT)
    {
        engine_speed_msg_no_received_count = MAX_TIME_COUNT;
    }
    engine_speed_msg_no_received_count++;
}

/**
 * @brief	从 CAN 报文中解析数据，更新至 separator_t 结构中
 * @note	在CAN接收完成中断中执行
 */
void can_data_update(separator_t *separator)
{
    if (can_receive_msg.ext_id == MOTOR_CTRL_MSG_ID)
    {
        clear_motor_ctrl_count();
        separator->can_data.motor_control_msg  = message_is_received;
        separator->can_data.target_speed       = can_receive_msg.data2 + (can_receive_msg.data3 << 8);
        separator->can_data.driect_control_cmd = can_receive_msg.data4;
    }
    else if (can_receive_msg.ext_id == ENGINE_SPEED_MSG_ID)
    {
        clear_engine_speed_count();
        separator->can_data.engine_speed_msg = message_is_received;
        separator->can_data.engine_speed     = can_receive_msg.data3;
    }
    else if (can_receive_msg.ext_id == AIR_TEMP_MSG_ID)
    {
        separator->can_data.temperature = 0.03125 * (can_receive_msg.data3 + (can_receive_msg.data4 << 8));
    }
    else
        return;
}

/**
 * @brief	更新油分器数据结构体
 * @param	结构体指针
 * @note	放置在定时器中断或在大循环处，周期性更新系统数据
 */
void separator_update(separator_t *separator)
{
    // 根据计数值判断是否接收到 CAN 报文
    if (engine_speed_msg_no_received_count >= MAX_TIME_COUNT)
    {
        // 刷新数据
        separator->can_data.engine_speed_msg = message_no_received;
        separator->can_data.engine_speed     = 0;
    }

    if (motor_control_msg_no_received_count >= MAX_TIME_COUNT)
    {
        // 刷新数据
        separator->can_data.engine_speed_msg   = message_no_received;
        separator->can_data.target_speed       = 0;
        separator->can_data.driect_control_cmd = 0;
    }

    update_engine_state(separator);
}